package ldk.xposed.dexreplace.ui

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.BaseAdapter
import android.widget.ListView
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_app.*
import ldk.xposed.dexreplace.*
import ldk.xposed.dexreplace.utils.ShellUtil
import java.io.File
import java.io.FileInputStream
import java.math.BigInteger
import java.security.MessageDigest

/**
 * Created by liangdengke on 2018/5/7.
 */
class AppInfoActivity: Activity() {

    companion object {
        private val TAG = "AppInfoActivity"
    }

    private lateinit var unSelectListView: ListView
    private lateinit var saveBtn: TextView
    private lateinit var replaceTextView: TextView

    private var selectDexFile: String? = null
    private var unSelectDexFiles = ArrayList<String>()
    private lateinit var unSelectAdapter: BaseAdapter
    private lateinit var packageNameInfo: String

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_app)
        unSelectListView = findViewById(R.id.lv_un_selected) as ListView
        saveBtn = findViewById(R.id.tv_save) as TextView
        replaceTextView = findViewById(R.id.tv_replace) as TextView

        val name = intent.getStringExtra("packageName")
        if (TextUtils.isEmpty(name)){
            throw IllegalArgumentException("packageName is null or empty")
        }
        packageNameInfo = name
        unSelectAdapter = DexFileAdapter(unSelectDexFiles)
        unSelectListView.adapter = unSelectAdapter
        unSelectListView.setOnItemClickListener { parent, view, position, id ->
            val element = unSelectDexFiles.removeAt(position)
            selectDexFile = element
            updateAdapter()
        }
        loadInfo()
        loadPackageInfo()
        saveBtn.setOnClickListener { onSaveClick() }
        saveBtn.isEnabled = false
        findViewById(R.id.btn_grant).setOnClickListener {
            ShellUtil.grant(packageNameInfo, Manifest.permission.READ_EXTERNAL_STORAGE)
            ShellUtil.grant(packageNameInfo, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        }
        findViewById(R.id.btn_clear_compile).setOnClickListener { ShellUtil.resetCompile(packageNameInfo) }
        replaceTextView.setOnClickListener {
            unSelectDexFiles.add(selectDexFile!!)
            selectDexFile = null
            updateAdapter(true)
        }
    }

    private fun loadPackageInfo() {
        val info = packageManager.getPackageInfo(packageNameInfo, 0)
        iv_icon.setImageDrawable(info.applicationInfo.loadIcon(packageManager))
        tv_app_name.text = info.applicationInfo.loadLabel(packageManager)
    }

    private fun onSaveClick(){
        Log.d(TAG, "onSaveClick: $selectDexFile")
        AlertDialog.Builder(this).setTitle("确认修改")
                .setMessage("使用$selectDexFile 进行替换Dex")
                .setPositiveButton("确认") { dialog, which ->
                    Thread{
                        val server = Server(this)
                        val maps = server.parseReplaceInfos()
                        val writeAction = {
                            server.updateReplaceInfo(maps)
                            ShellUtil.forceStop(packageNameInfo)
                            ShellUtil.resetCompile(packageNameInfo)
                        }
                        if (selectDexFile == null){
                            if (maps.containsKey(packageNameInfo)){
                                maps.remove(packageNameInfo)
                                writeAction.invoke()
                            }
                        }else{
                            maps[packageNameInfo] = ReplaceDexInfo(MainActivity.dexFileDir().absolutePath + "/" + selectDexFile!!, packageNameInfo)
                            writeAction.invoke()
                        }
                    }.start()
                    setResult(Activity.RESULT_OK)
                }.show()
    }

    private fun md5OfFile(fileName: String): String{
        val file = File(fileName)
        val inputStream = FileInputStream(file)
        val digest = MessageDigest.getInstance("MD5")
        val buffer = ByteArray(1024)
        var len: Int = 0
        while (true){
            len = inputStream.read(buffer, 0, 1024)
            if (len == -1)
                break
            digest.update(buffer, 0, len)
        }
        inputStream.close()
        val bigInt = BigInteger(1, digest.digest())
        return bigInt.toString(16)
    }

    private fun updateAdapter(shouldSave: Boolean = true){
        unSelectAdapter.notifyDataSetChanged()
        if (shouldSave){
            saveBtn.isEnabled = true
        }
        replaceTextView.visibility =
                if (TextUtils.isEmpty(selectDexFile))
                    View.GONE
                else{
                    replaceTextView.text = selectDexFile
                    View.VISIBLE
                }
    }

    private fun loadInfo() {
        Thread{
            MainActivity.scanDex { dexFiles:List<String>, dexDir ->
                val server = Server(this)
                val dexReplaces = MainActivity.loadDexByReplaceDexInfo(server.parseReplaceInfo(packageNameInfo))
                runOnUiThread {
                    unSelectDexFiles.clear()
                    selectDexFile = if (dexReplaces.isEmpty()) null else dexReplaces[0]
                    unSelectDexFiles.addAll(dexFiles.filterNot { dexReplaces.contains(it) })
                    updateAdapter(false)
                }
            }
        }.start()
    }
}